﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;

namespace INSTA.Concepts.TemplateMethodPattern
{
    public class XmlFile : AbstractFile
    {
        XmlTextWriter xmlWriter;

        /// <summary>
        /// Initializes a new instance of the <see cref="XmlFile"/> class.
        /// </summary>
        /// <param name="customer">L'objet <see cref="Customer"/> devant être sérialisé dans le fichier.</param>
        /// <param name="fileName">Le nom de fichier dans lequel écrire les données.</param>
        public XmlFile(Person person, string fileName) : base(person, fileName)
        {
            xmlWriter               = new XmlTextWriter(fileName + ".xml", Encoding.UTF8);
            xmlWriter.Formatting    = Formatting.Indented;            
        }
        
        /// <summary>
        /// Méthode permettant d'écrire l'en-tête de fichier.
        /// Dans l'implémentation de cette classe, on ne fait qu'ouvrir le fichier..
        /// </summary>
        public override void WriteHeader()
        {
            xmlWriter.WriteStartDocument();

            xmlWriter.WriteStartElement(typeof(Person).Name); //--> <person>
        }

        /// <summary>
        /// Méthode permettant d'écrire les données du fichier.
        /// Dans l'implémentation fournie par cette classe, les données seront écrites
        /// au format XML.
        /// </summary>
        public override void WriteData()
        {
            Type type = _person.GetType();

            // On obtient par réflexion les valeurs de toutes les propriétés publiques de l'objet Customer traité..             
            foreach (var propInfo in type.GetProperties(GetStandardBindings()))
            {
                // on obtient le nom et la valeur de la propriété en cours de traitement..
                string propName     = propInfo.Name;
                string propValue    = _person.GetPropertyValue(propName).ToString(); ;

                // et l'on écrit le node Xml correspondant à la propriété dans le fichier..
                xmlWriter.WriteElementString(propName, propValue); 
                // Pour une propriété donnée on obtient.
                //      |--> <Name>Le Nom</Name>
            }
        }

        /// <summary>
        /// Méthode permettant d'écrire la fin du fichier Xml        
        /// </summary>
        public override void WriteFooter()
        {
            // écrit la balise de fin ( "</person>" )..
            xmlWriter.WriteEndElement();

            // écrit la balise de fin de document..
            xmlWriter.WriteEndDocument();

            // Flush les informations et ferme le fichier..
            xmlWriter.Flush();
            xmlWriter.Close();
        }
    }
    
}
